package wsi.exp.calibrate;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import org.rygh.core.face.IHasName;
import org.rygh.core.util.UIo;

import wsi.exp.calibrate.GatherCalibration.Result.Tuple;
import wsi.function.Function;
import wsi.function.FunctionController;
import wsi.script.AppConfig;
import wsi.ws.WebServices;
import app.App;

@Deprecated
public class GatherCalibration extends App {

	static class Result implements IHasName {
		static class Tuple implements IHasName, Comparable<Tuple> {
			final String threshold;
			double precision;
			double recall;
			int hit;
			int total;

			public Tuple(String name) {
				threshold = name;
			}

			@Override
			public int compareTo(Tuple o) {
				return threshold.compareTo(o.threshold);
			}

			@Override
			public String getName() {
				return threshold;
			}

			@Override
			public String toString() {
				return String.format("%.4f, %.4f, %d, %d", precision, recall,
						hit, total);
			}
		}

		final Map<String, Tuple> tupleMap = new HashMap<>();

		String name;
		int goldset;

		public Result(String name) {
			this.name = name;
		}

		@Override
		public String getName() {
			return name;
		}

		public List<Tuple> getTuples() {
			List<Tuple> list = new ArrayList<>();

			for (Tuple i : tupleMap.values())
				list.add(i);

			Collections.sort(list);

			return list;
		}

		public void load(String line) {
			String key = line.split(":")[0];

			Tuple tuple;

			if (tupleMap.containsKey(key))
				tuple = tupleMap.get(key);
			else {
				tuple = new Tuple(key);
				tupleMap.put(key, tuple);
			}

			if (line.contains(":Precision"))
				tuple.precision = Double.parseDouble(line.split(" ")[1]);
			else if (line.contains(":Recall"))
				tuple.recall = Double.parseDouble(line.split(" ")[1]);
			else if (line.contains(":Total"))
				tuple.total = Integer.parseInt(line.split(" ")[1]);
			else if (line.contains(":Hit"))
				tuple.hit = Integer.parseInt(line.split(" ")[1]);
		}

		@Override
		public String toString() {
			StringBuilder sb = new StringBuilder();
			sb.append(name + ", " + goldset + ", ");

			List<Tuple> list = getTuples();

			for (Tuple i : list) {
				sb.append(i.toString());
				sb.append(", ");
			}

			return sb.toString();
		}
	}

	public static void main_old() {
		init();
		AppConfig.init();

		GatherCalibration app = new GatherCalibration();

		for (WebServices service : WebServices.values()) {
			app.setService(service.name());
			app.compute();
		}

		app.save();

		bye();
	}

	private final Logger log = Logger.getLogger(getClass().getName());
	private final List<Result> results = new ArrayList<>();

	private String service;

	public GatherCalibration() {
	}

	private void compute() {
		log.info("computing");

		File file;
		Result result;

		for (Function f : FunctionController.shared().getFunctions(service)) {
			log.info("processing " + f.getName());

			// file = new File(Config.GOLD_SET_DIR, String.format(
			// "%s/%s/results.txt", service, f.getName()));
			file = new File(String.format("%s/%s/results.txt", service,
					f.getName()));

			if (!file.exists())
				continue;

			result = new Result(service + "/" + f.getName());
			String[] lines = UIo.readFile(file).split("\r\n");

			for (String line : lines) {
				if (line.trim().isEmpty())
					continue;

				if (line.startsWith("Gold"))
					result.goldset = Integer.parseInt(line.split(" ")[1]);
				else if (line.charAt(4) == ':')
					result.load(line);
			}

			results.add(result);
		}

	}

	private void save() {
		// UIo.saveFile(new File(Config.GOLD_SET_DIR, "results.csv"),
		// toString());
		// UIo.saveFile(new File(Config.GOLD_SET_DIR, "results.txt"),
		// toString());
	}

	public void setService(String service) {
		this.service = service;
	}

	@Override
	public String toString() {
		StringBuilder sbuilder = new StringBuilder();

		Result res = results.get(0);
		List<Tuple> list = res.getTuples();

		for (Tuple i : list) {
			sbuilder.append(i.getName());
			sbuilder.append(", ");
		}
		sbuilder.append("\r\nFunction, Gold, ");

		for (int i = 0; i < list.size(); i++) {
			sbuilder.append("Precision, Recall, Hit, Total, ");
		}
		sbuilder.append("\r\n");

		for (Result r : results) {
			sbuilder.append(r.toString());
			sbuilder.append("\r\n");
		}

		return sbuilder.toString();
	}

}
